-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.


-- Description: 公共接口
local log           = require 'mc.logging'

local CHARACTER_MAX = 0x80 - 1
local LF            = 0x0A -- 换行
local CR            = 0x0D -- 回车
local SPACE         = 0x20 -- 空格

local common        = {}

common.DEFAULT_MANU = 'Huawei'
common.MfgDate      = '1996/01/01 Mon 00:00:00'


common.SELF_TEST_NO_ERROR          = 0x55
common.SELF_TEST_NOT_IMPLEMENT     = 0x56
common.SELF_TEST_CORRUPT_INACCESS  = 0x57
common.SELF_TEST_FATAL_HW_ERR      = 0x58
common.FRU_ID_MAX_AUTO_ALLOC       = 63
common.FRU_CONTROL_GRACEFUL_REBOOT = 2
common.MAX_UID_LENGTH              = 64
common.COMP_CODE_PARA_NOT_SUPPORT  = 0x80
common.TYPE_FRU_ID                 = 1
common.TYPE_POSITION_ID            = 2
common.TYPE_SILK_TEXT              = 3

common.ELABEL_INFO_BLOCK_OFFSET = 0x0C00
common.ELABEL_MULTI_AREA_OFFSET = 0x3780
common.ELABEL_EXTEND_INFO_BLOCK_OFFSET = 0x3000

common.COMPONENT_TYPE_PS                = 3
common.COMPONENT_TYPE_FAN               = 4
common.COMPONENT_TYPE_HDD_BACKPLANE     = 5
common.COMPONENT_TYPE_RAID_CARD         = 6
common.COMPONENT_TYPE_PCIE_CARD         = 8
common.COMPONENT_TYPE_AMC               = 9
common.COMPONENT_TYPE_MEZZ_CARD         = 11
common.COMPONENT_TYPE_NIC_CARD          = 13
common.COMPONENT_TYPE_MEMORY_BOARD      = 14
common.COMPONENT_TYPE_PCIE_RISER        = 15
common.COMPONENT_TYPE_MAINBOARD         = 16
common.COMPONENT_TYPE_CHASSIS_BACKPLANE = 22
common.COMPONENT_TYPE_FANBOARD          = 24
common.COMPONENT_TYPE_MMC               = 27
common.COMPONENT_TYPE_BASEBOARD         = 28
common.COMPONENT_TYPE_FABRIC            = 30
common.COMPONENT_TYPE_SWITCH_MEZZ       = 31
common.COMPONENT_TYPE_IOBOARD           = 35
common.COMPONENT_TYPE_CPUBOARD          = 36
common.COMPONENT_TYPE_PCIE_ADAPTER      = 38
common.COMPONENT_TYPE_EXPAND_BOARD      = 45
common.COMPONENT_TYPE_TIANCHI_EXPBOARD  = 50
common.COMPONENT_TYPE_GPU_BOARD         = 64
common.CM_DEVICE_TYPE_CONVERGE_BOARD    = 91
common.CM_DEVICE_TYPE_SOC_BOARD         = 92
common.CM_DEVICE_TYPE_TIANCHI_EXPBOARD  = 93
common.COMPONENT_TYPE_ALL               = 0xff
common.COMPONENT_NUM_ALL                = 0xff
common.DEVICE_INFO_LEN                  = 511


common.type_table = {
    [0] = 'CPU',                          -- 0x00：CPU
    [1] = 'Memory',                       -- 0x01：内存
    [2] = 'Disk',                         -- 0x02：硬盘
    [3] = 'PSU',                          -- 0x03：电源
    [4] = 'Fan',                          -- 0x04：风扇
    [5] = 'Disk Backplane',               -- 0x05：硬盘背板
    [6] = 'RAID Card',                    -- 0x06：RAID扣卡
    [7] = 'UNKNOWN',                      -- 0x07：未定义
    [8] = 'PCIe Card',                    -- 0x08：PCIe标卡
    [9] = 'AMC',                          -- 0x09：AMC板
    [10] = 'HBA',                         -- 0x0A：HBA卡
    [11] = 'Mezz Card',                   -- 0x0B：Mezz扣卡
    [12] = 'UNKNOWN',                     -- 0x0C：未定义
    [13] = 'NIC',                         -- 0x0D：网卡扣卡
    [14] = 'Memory Board',                -- 0x0E：内存板
    [15] = 'PCIe Riser',                  -- 0x0F：PCIe Riser卡
    [16] = 'Mainboard',                   -- 0x10：主板
    [17] = 'LCD',                         -- 0x11：LCD
    [18] = 'Chassis',                     -- 0x12：机箱
    [19] = 'NCM',                         -- 0x13：NC板
    [20] = 'Switch Module',               -- 0x14：交换板
    [21] = 'Storage Board',               -- 0x15：存储板
    [22] = 'Chassis Backplane',           -- 0x16：机框背板
    [23] = 'HMM/CMC',                     -- 0x17：SMM板/CMC
    [24] = 'Fan Backplane',               -- 0x18：风扇背板
    [25] = 'PSU Backplane',               -- 0x19：电源背板
    [26] = 'BMC',                         -- 0x1A：BMC/BMC板
    [27] = 'MM/MMC',                      -- 0x1B：MMC(MM)板
    [28] = 'Twin Node Backplane',         -- 0x1C：双胞胎底板
    [29] = 'Base Plane',                  -- 0x1D：Base (交换平面)
    [30] = 'Fabric Plane',                -- 0x1E：Fabric (交换平面)
    [31] = 'Switch Mezz',                 -- 0x1F：交换扣卡(如FC GW扣卡/FCoE/M8PA)
    [32] = 'LED',                         -- 0x20：LED
    [33] = 'SD Card',                     -- 0x21：SD卡
    [34] = 'Security Module',             -- 0x22：TPM/TCM卡
    [35] = 'I/O Board',                   -- 0x23：IO板
    [36] = 'CPU Board',                   -- 0x24：处理器板
    [37] = 'RMC',                         -- 0x25：RMC板
    [38] = 'PCIe Adapter',                -- 0x26：PCIE SSD盘转接卡
    [39] = 'PCH',                         -- 0x27：PCH(南桥)
    [40] = 'Cable',                       -- 0x28：线缆/内部连接
    [41] = 'Port',                        -- 0x29：端口
    [42] = 'LSW',                         -- 0x2A：LSW
    [43] = 'PHY',                         -- 0x2B：PHY
    [44] = 'System',                      -- 0x2C：业务系统/产品
    [45] = 'M.2 Transfer Card',           -- 0x2D：M.2转接卡
    [46] = 'LED Board',                   -- 0x2E：LED转接板
    [47] = 'LPM',                         -- 0x2F：LPM
    [48] = 'PIC Card',                    -- 0x30：PIC卡（灵活插卡）
    [49] = 'Button',                      -- 0x31：按钮
    [50] = 'Expander',                    -- 0x32：Expander
    [51] = 'CPI',                         -- 0x33：CPI(集中控制分区单元，Central Partition Interconnect Module )
    [52] = 'ACM',                         -- 0x34：ACM(系统时钟板，Advanced Clock Module)
    [53] = 'CIM',                         -- 0x35：CIM(中心接口模块，Central Interface Module)
    [54] = 'PFM',                         -- 0x36：PFM(电源风扇合一模块)
    [55] = 'KPAR',                        -- 0x37：KPAR(多分区系统)
    [56] = 'JC',                          -- 0x38：JC芯片
    [57] = 'SCM',                         -- 0x39：SCM(系统计算模块，指CPU+内存的计算单元)
    [58] = 'Minisas HD channel',          -- 0x3A：MINISAS HD通道
    [59] = 'SATA DOM channel',            -- 0x3B：SATA DOM通道
    [60] = 'GE channel',                  -- 0x3C：GE通道
    [61] = 'XGE channel',                 -- 0x3D：XGE通道
    [62] = 'PCIe Switch',                 -- 0x3E：PCIe Switch
    [63] = 'Interface Device',            -- 0x3F：接口器件
    [64] = 'xPU Carrier Board',           -- 0x40：xPU载板
    [65] = 'Disk BaseBoard',              -- 0x41：硬盘底板（CH222V3的SESA）
    [66] = 'VGA Interface Card',          -- 0x42：VGA接口卡
    [67] = 'Pass-Through Card',           -- 0x43：直通卡(SAS直通卡等)
    [68] = 'Logical Driver',              -- 0x44：逻辑盘
    [69] = 'PCIe Retimer',                -- 0x45：PCIe Retimer
    [70] = 'PCIe Repeater',               -- 0x46：PCIe Reperter
    [71] = 'SAS',                         -- 0x47：SAS
    [72] = 'Memory Channel',              -- 0x48：内存通道
    [73] = 'BMA',                         -- 0x49：BMA
    [74] = 'LOM',                         -- 0x4A：板载网卡
    [75] = 'Signal Adapter Board',        -- 0x4B：信号转接板
    [76] = 'Horizontal Connection Board', -- 0x4C：水平转接板
    [77] = 'Node',                        -- 0x4D：节点
    [78] = 'Asset Locate Board',          -- 0x4E：资产管理控制板
    [79] = 'Unit',                        -- 0x4F：机柜U位
    [80] = 'RMM',                         -- 0x50：机柜管理模块
    [81] = 'Rack',                        -- 0x51：机柜
    [82] = 'BBU',                         -- 0x52：备电
    [83] = 'OCP Card',                    -- 0x53：OCP扣卡
    [84] = 'Leakage Detection Card',      -- 0x54：漏液检测卡
    [85] = 'MESH Card',                   -- 0x55：MESH卡
    [86] = 'NPU',                         -- 0x56：神经网络计算芯片
    [87] = 'CIC Card',                    -- 0x57：融合接口卡
    [88] = 'Expansion Module',            -- 0x58：Expansion Module
    [89] = 'Fan Module',                  -- 0x59：风扇模块
    [90] = 'AR Card',                     -- 0x5A：AR卡
    [91] = 'Converge Board',              -- 0x5B：汇聚板
    [92] = 'SoC Board',                   -- 0x5C：SoC主板
    [93] = 'Expand Board',                -- 0x5D：扩展板
    [94] = 'HiAM',                        -- 0x5E:HiAM
    [95] = 'OpticalModule',               -- 0x5F：光模块
    [96] = 'HDU',                         -- 0x60:HDU
    [98] = 'LCN',                         -- 0x62：区域计算网络    
    [192] = 'BCU',                        -- 0xC0：基础计算组件
    [193] = 'EXU',                        -- 0xC1：系统扩展组件
    [194] = 'SEU',                        -- 0xC2：存储扩展组件
    [195] = 'IEU',                        -- 0xC3：IO扩展组件
    [196] = 'CLU'                         -- 0xC4：散热组件
}

common.chassis_type = {
    "Unspecified",        "Other",                "Unknown",
    "Desktop",            "Low Profile Desktop",  "Pizza Box",
    "Mini Tower",         "Tower",                "Portable",
    "LapTop",             "Notebook",             "Hand Held",
    "Docking Station",    "All in One",           "Sub Notebook",
    "Space-saving",       "Lunch Box",            "Main Server Chassis",
    "Expansion Chassis",  "SubChassis",           "Bus Expansion Chassis",
    "Peripheral Chassis", "RAID Chassis",         "Rack Mount Chassis",
    "Sealed-case PC",     "Multi-system Chassis", "Compact PCI",
    "Advanced TCA",       "Blade",                "Blade Enclosure",
    "Tablet",             "Convertible",          "Defachable",
    "IoT Gateway",        "Embedded PC",          "Mini PC",
    "Stick PC"
}

common.property                        = {}

common.property['ChassisType']         = { 1, 0 }
common.property['ChassisPartNumber']   = { 1, 1 }
common.property['ChassisSerialNumber'] = { 1, 2 }
common.property['ChassisCustomInfo']   = { 1, 3 }

common.property['MfgDate']             = { 2, 0 }
common.property['BoardManufacturer']   = { 2, 1 }
common.property['BoardProductName']    = { 2, 2 }
common.property['BoardSerialNumber']   = { 2, 3 }
common.property['BoardPartNumber']     = { 2, 4 }
common.property['BoardFRUFileID']      = { 2, 5 }
common.property['BoardCustomInfo']     = { 2, 6 }

common.property['AssetTag']            = { 3, 5 }
common.property['ManufacturerName']    = { 3, 0 }
common.property['ProductCustomInfo']   = { 3, 7 }
common.property['ProductFRUFileID']    = { 3, 6 }
common.property['ProductName']         = { 3, 1 }
common.property['ProductPartNumber']   = { 3, 2 }
common.property['ProductSerialNumber'] = { 3, 4 }
common.property['ProductVersion']      = { 3, 3 }

common.property['SystemManufacturer']  = { 6, 0 }
common.property['SystemProductName']   = { 6, 1 }
common.property['SystemVersion']       = { 6, 2 }
common.property['SystemSerialNumber']  = { 6, 3 }

common.INFO_FRU_PRESENT             = 0x01
common.INFO_FRU_UNPRESENT           = 0x00

common.INFO_TYPE_DFT_PRESENT        = 0x00
common.INFO_TYPE_DFT_PRODUCT_ID     = 0x01
common.INFO_TYPE_DFT_BOARD_ID       = 0x02
common.INFO_TYPE_DFT_PCB_ID         = 0x03
common.INFO_TYPE_DFT_NAME           = 0x04
common.INFO_TYPE_DFT_COMPONENT_TYPE = 0x05
common.INFO_TYPE_DFT_BOM_ID         = 0x06
common.INFO_TYPE_DFT_SLOT_ID        = 0x07
common.INFO_TYPE_DFT_SDI_UNIQUE_ID  = 0x08

common.END_MASK                     = 0x80

common.SYSTEM_DATA_LEN              = 153
common.FRU_FILE_LEN                 = 2048
common.FRU_OFFSET                   = 128
common.SYSTEM_OFFSET                = 2176
common.UNIQUE_OFFSET                = 100
common.UNIQUE_LENGTH                = 24

common.FRU_AREA                     = {
    CHASSIS = 1,
    BOARD = 2,
    PRODUCT = 3,
    EXTENDELABLE = 5,
    SYSTEM = 6,
}

common.FRU_FIELD                    = {
    CHASSIS = {
        TYPE = 0,
        PARTNUMBER = 1
    },

    BOARD = {
        MFGDATE = 0,
        MANUFACTURER = 1,
        PRODUCTNAME = 2,
        SERIALNUMBER = 3,
        PARTNUMBER = 4,
        FRUFILEID = 5,
        EXTRA = 6,
    },

    PRODUCT = {
        MANUFACTURER = 0,
        NAME = 1,
        PARTNUMBER = 2,
        VERSION = 3,
        SERIALNUMBER = 4,
        ASSETTAG = 5,
        FRUFILEID = 6,
        EXTRA = 7,
    },

    EXTENDELABLE = {
        FIELAD = 1,
    },

    SYSTEM = {
        MANUFACTURE = 0,
        PRODUCTNAME = 1,
        VERSION = 2,
        SERIALNUMBER = 3,
    }
}

-- 非南向设备树版本关闭写保护为0
common.EEPROM_WRITE_PROTECT = {
    OPEN = 1,
    CLOSE = 0
}

function common.validate_byte(area, field, str)
    -- 2 0为MfgDate,1 0为ChassisType,6 2为SystemVersion
    local property_table = {
        [1] = { [0] = true },
        [2] = { [0] = true },
        [6] = { [2] = true }
    }

    if property_table[area] and property_table[area][field] then
        return true
    end

    local byte
    for i = 1, #str do
        byte = string.byte(str, i, i)
        if (byte < SPACE or byte >= CHARACTER_MAX) and (byte ~= LF and byte ~= CR) then
            log:error('frudata have special characters(%2X)', byte)
            return false
        end
    end
    return true
end

function common.format_system_id(path)
    local index = string.find(path, 'Systems')
    local left = string.find(path, '/', index)
    local right = string.find(path, '/', left + 1)
    return tonumber(string.sub(path, left + 1, right - 1))
end

-- MfgDate时间戳字符串转为字节串
function common.string_to_char(hex_string)
    -- 3字节数据，长度必须为6
    if #hex_string ~= 6 then
        log:error('The length of mfgdate(%d) is not equal to 6', #hex_string)
        return ''
    end

    local ret = ''
    -- 匹配以任意16进制字符组成的字符串
    if string.match(hex_string, "^%x+$") then
        -- 每2个字符表示1字节的数据，共3个字节
        for i = 1, 6, 2 do
            ret = ret .. string.char(tonumber(string.sub(hex_string, i, i + 1), 16)) -- 整形转为char类型,匹配c代码结构
        end
    end

    return ret
end

function common.copy_str(a, n)
    local len = #a
    if n <= 0 then
        return ''
    end
    local i = 1
    while i < n do
        if i * 2 >= n then
            a = a .. string.sub(a, 1, (n - i) * len)
            break
        else
            a = a .. a
        end
        i = i * 2
    end
    return a
end

return common
